ANALYSE DES VENTES D’UN SITE DE E-COMMERCE

Import et installation

import pandas as pd
import numpy as np
import re
import matplotlib.pyplot as plt
import seaborn as sns
import skimpy
from skimpy import skim
import plotly.express as px

Création du DataFrame de base

data = pd.read_csv("shopping_trends.csv", sep=",", low_memory=False)
df = data.copy()
df.shape
(3900, 19)
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3900 entries, 0 to 3899
Data columns (total 19 columns):
 #   Column                    Non-Null Count  Dtype
---  ------                    --------------  -----
 0   Customer ID               3900 non-null   int64
 1   Age                       3900 non-null   int64
 2   Gender                    3900 non-null   object
 3   Item Purchased            3900 non-null   object
 4   Category                  3900 non-null   object
 5   Purchase Amount (USD)     3900 non-null   int64
 6   Location                  3900 non-null   object
 7   Size                      3900 non-null   object
 8   Color                     3900 non-null   object
 9   Season                    3900 non-null   object
 10  Review Rating             3900 non-null   float64
 11  Subscription Status       3900 non-null   object
 12  Payment Method            3900 non-null   object
 13  Shipping Type             3900 non-null   object
 14  Discount Applied          3900 non-null   object
 15  Promo Code Used           3900 non-null   object
 16  Previous Purchases        3900 non-null   int64
 17  Preferred Payment Method  3900 non-null   object
 18  Frequency of Purchases    3900 non-null   object
dtypes: float64(1), int64(4), object(14)
memory usage: 579.0+ KB
df.describe().T
count mean std min 25% 50% 75% max
Customer ID 3900.0 1950.500000 1125.977353 1.0 975.75 1950.5 2925.25 3900.0
Age 3900.0 44.068462 15.207589 18.0 31.00 44.0 57.00 70.0
Purchase Amount (USD) 3900.0 59.764359 23.685392 20.0 39.00 60.0 81.00 100.0
Review Rating 3900.0 3.749949 0.716223 2.5 3.10 3.7 4.40 5.0
Previous Purchases 3900.0 25.351538 14.447125 1.0 13.00 25.0 38.00 50.0
df.describe(include="object").T
count unique top freq
Gender 3900 2 Male 2652
Item Purchased 3900 25 Blouse 171
Category 3900 4 Clothing 1737
Location 3900 50 Montana 96
Size 3900 4 M 1755
Color 3900 25 Olive 177
Season 3900 4 Spring 999
Subscription Status 3900 2 No 2847
Payment Method 3900 6 Credit Card 696
Shipping Type 3900 6 Free Shipping 675
Discount Applied 3900 2 No 2223
Promo Code Used 3900 2 No 2223
Preferred Payment Method 3900 6 PayPal 677
Frequency of Purchases 3900 7 Every 3 Months 584
skim(df)
╭──────────────────────────────────────────────── skimpy summary ─────────────────────────────────────────────────╮
│          Data Summary                Data Types                                                                 │
│ ┏━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┓ ┏━━━━━━━━━━━━━┳━━━━━━━┓                                                          │
│ ┃ dataframe          Values ┃ ┃ Column Type  Count ┃                                                          │
│ ┡━━━━━━━━━━━━━━━━━━━╇━━━━━━━━┩ ┡━━━━━━━━━━━━━╇━━━━━━━┩                                                          │
│ │ Number of rows    │ 3900   │ │ string      │ 14    │                                                          │
│ │ Number of columns │ 19     │ │ int64       │ 4     │                                                          │
│ └───────────────────┴────────┘ │ float64     │ 1     │                                                          │
│                                └─────────────┴───────┘                                                          │
│                                                     number                                                      │
│ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━┳━━━━━━━┳━━━━━━━━┳━━━━━━━━━━┳━━━━━━┳━━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━┳━━━━━━━━┓  │
│ ┃ column_name               NA   NA %   mean    sd        p0    p25     p50    p75    p100  hist   ┃  │
│ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━╇━━━━━━━╇━━━━━━━━╇━━━━━━━━━━╇━━━━━━╇━━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━╇━━━━━━━━┩  │
│ │ Customer ID               0    0  1950    1126   1 975.8 1950 29253900▇▇▇▇▇▇ │  │
│ │ Age                       0    0 44.07   15.21  18    31   44   57  70▇▇▇▇▇▇ │  │
│ │ Purchase Amount (USD)     0    0 59.76   23.69  20    39   60   81 100▇▇▇▇▇▇ │  │
│ │ Review Rating             0    0  3.75  0.7162 2.5   3.1  3.7  4.4   5▇▇▇▇▇▇ │  │
│ │ Previous Purchases        0    0 25.35   14.45   1    13   25   38  50▇▇▇▇▇▇ │  │
│ └──────────────────────────┴─────┴───────┴────────┴──────────┴──────┴────────┴───────┴───────┴──────┴────────┘  │
│                                                     string                                                      │
│ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┓  │
│ ┃ column_name                            NA     NA %       words per row             total words         ┃  │
│ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━┩  │
│ │ Gender                                   0        0                       1               3900 │  │
│ │ Item Purchased                           0        0                       1               3900 │  │
│ │ Category                                 0        0                       1               3900 │  │
│ │ Location                                 0        0                     1.2               4657 │  │
│ │ Size                                     0        0                       1               3900 │  │
│ │ Color                                    0        0                       1               3900 │  │
│ │ Season                                   0        0                       1               3900 │  │
│ │ Subscription Status                      0        0                       1               3900 │  │
│ │ Payment Method                           0        0                     1.5               5861 │  │
│ │ Shipping Type                            0        0                     1.8               7148 │  │
│ │ Discount Applied                         0        0                       1               3900 │  │
│ │ Promo Code Used                          0        0                       1               3900 │  │
│ │ Preferred Payment Method                 0        0                     1.5               5819 │  │
│ │ Frequency of Purchases                   0        0                     1.3               5068 │  │
│ └───────────────────────────────────────┴───────┴───────────┴──────────────────────────┴─────────────────────┘  │
╰────────────────────────────────────────────────────── End ──────────────────────────────────────────────────────╯

Taux de remplissage des colonnes

# Calculer le taux de remplissage pour chaque colonne
column_fill_rates = df.notna().mean() * 100

# Afficher le taux de remplissage pour chaque colonne
column_fill_rates
Customer ID                 100.0
Age                         100.0
Gender                      100.0
Item Purchased              100.0
Category                    100.0
Purchase Amount (USD)       100.0
Location                    100.0
Size                        100.0
Color                       100.0
Season                      100.0
Review Rating               100.0
Subscription Status         100.0
Payment Method              100.0
Shipping Type               100.0
Discount Applied            100.0
Promo Code Used             100.0
Previous Purchases          100.0
Preferred Payment Method    100.0
Frequency of Purchases      100.0
dtype: float64
df.isnull().sum()
Customer ID                 0
Age                         0
Gender                      0
Item Purchased              0
Category                    0
Purchase Amount (USD)       0
Location                    0
Size                        0
Color                       0
Season                      0
Review Rating               0
Subscription Status         0
Payment Method              0
Shipping Type               0
Discount Applied            0
Promo Code Used             0
Previous Purchases          0
Preferred Payment Method    0
Frequency of Purchases      0
dtype: int64

L’ensemble des colonnes étant remplies et ne comportant aucune valeur nulle, nous pourrons faire une analyse complète des données.

Produits les plus vendus

item_purchased=df['Item Purchased'].value_counts().reset_index()
item_purchased
Item Purchased count
0 Blouse 171
1 Pants 171
2 Jewelry 171
3 Shirt 169
4 Dress 166
5 Sweater 164
6 Jacket 163
7 Coat 161
8 Sunglasses 161
9 Belt 161
10 Sandals 160
11 Socks 159
12 Skirt 158
13 Scarf 157
14 Shorts 157
15 Hat 154
16 Handbag 153
17 Hoodie 151
18 Shoes 150
19 T-shirt 147
20 Sneakers 145
21 Boots 144
22 Backpack 143
23 Gloves 140
24 Jeans 124
plt.figure(figsize=(20, 8))
df['Item Purchased'].value_counts().plot(kind='pie',autopct='%1.1f%%')
plt.title('Distribution de Item purchased')
plt.ylabel("")
plt.tight_layout()
plt.show()
output_17_0.png

On remarque une répartition plutôt égale de la vente des produits. Le produit le plus vendu a été 171 fois, & le moins vendu 124 fois.

item_revenu = df.groupby('Item Purchased')['Purchase Amount (USD)'].sum()
item_revenu.sort_values(ascending=False)
Item Purchased
Blouse        10410
Shirt         10332
Dress         10320
Pants         10090
Jewelry       10010
Sunglasses     9649
Belt           9635
Scarf          9561
Sweater        9462
Shorts         9433
Skirt          9402
Hat            9375
Coat           9275
Socks          9252
Jacket         9249
T-shirt        9248
Shoes          9240
Sandals        9200
Boots          9018
Handbag        8857
Hoodie         8767
Backpack       8636
Sneakers       8635
Gloves         8477
Jeans          7548
Name: Purchase Amount (USD), dtype: int64
columns_to_display = ['Item Purchased','Purchase Amount (USD)']
df[columns_to_display]
Item Purchased Purchase Amount (USD)
0 Blouse 53
1 Sweater 64
2 Jeans 73
3 Sandals 90
4 Blouse 49
... ... ...
3895 Hoodie 28
3896 Backpack 49
3897 Belt 33
3898 Shoes 77
3899 Handbag 81

3900 rows × 2 columns

On constate que le produit qui rapport le plus d’argent est la blouse ce qui est cohérent avec le fait que ça soit l’item le plus vendu et le plus cher.

Les Catégories

df['Category'].value_counts()
Category
Clothing       1737
Accessories    1240
Footwear        599
Outerwear       324
Name: count, dtype: int64
# Calculer la distribution des catégories
category_counts = df['Category'].value_counts()

# Tracer un pie chart
category_counts.plot(kind='pie', autopct='%1.1f%%', figsize=(8, 8), colors=sns.color_palette('Set3', len(category_counts)))

# Ajouter un titre
plt.title('Répartition des catégories de produits')

# Afficher le graphique
plt.tight_layout()
plt.show()
output_24_0.png

La catégories présente en plus grande proprotion est Clothing ( Vêtements) suivi d’Acessories ( Acessoires)

# Regrouper les données par 'Category' et calculer la somme des 'Purchase Amount (USD)'
category_revenue = df.groupby('Category')['Purchase Amount (USD)'].sum().reset_index()

# Trier les résultats par montant décroissant
category_revenue = category_revenue.sort_values(by='Purchase Amount (USD)', ascending=False)

# Afficher le résultat
display(category_revenue)
Category Purchase Amount (USD)
1 Clothing 104264
0 Accessories 74200
2 Footwear 36093
3 Outerwear 18524

La catégorie qui rapporte le plus à l’entreprise est Clothing, ce qui est cohérent avec le fait que ça la catégorie la plus vendue.

Ventes par genre

df['Gender'].value_counts().plot(kind='pie',autopct='%1.1f%%')
plt.title('Distribution par genre')
plt.tight_layout()
output_29_0.png

Ce sont majoritairement des hommes qui achètent sur ce site.

clothing = df[df['Category'] == 'Clothing']
clothing['Gender'].value_counts().plot(kind='pie',autopct='%1.1f%%')
plt.title('Distribution par genre')
plt.tight_layout()
output_31_0.png
accessories = df[df['Category'] == 'Accessories']
accessories['Gender'].value_counts().plot(kind='pie',autopct='%1.1f%%')
plt.title('Distribution par genre')
plt.tight_layout()
output_32_0.png
footwear = df[df['Category'] == 'Footwear']
footwear['Gender'].value_counts().plot(kind='pie',autopct='%1.1f%%')
plt.title('Distribution par genre')
plt.tight_layout()
output_33_0.png

On remarque que la grande majorité des acheteurs sont des hommes

outerwear = df[df['Category'] == 'Outerwear']
outerwear['Gender'].value_counts().plot(kind='pie',autopct='%1.1f%%')
plt.title('Distribution par genre')
plt.tight_layout()
output_35_0.png

La répartition des genres par catégories restent approximativement la même pour tous les types d’item

Age des acheteurs

df["Age"].describe()
count    3900.000000
mean       44.068462
std        15.207589
min        18.000000
25%        31.000000
50%        44.000000
75%        57.000000
max        70.000000
Name: Age, dtype: float64
fig, axes = plt.subplots(1, 2, figsize=(12, 4))

sns.histplot(data=df, x="Age", kde=True, ax=axes[0])
sns.boxplot(data=df, x="Age")
<Axes: xlabel='Age'>
output_39_1.png
# Calculer les statistiques de base pour la colonne 'Age'
age_stats = df['Age'].describe()

# Afficher les valeurs du minimum, du maximum et de la médiane
print(f"Min: {age_stats['min']}")
print(f"Max: {age_stats['max']}")
print(f"Median: {age_stats['50%']}")
Min: 18.0
Max: 70.0
Median: 44.0
df_sorted = df.sort_values(by=["Age", "Gender"])
df['Age Group'] = pd.cut(df['Age'], bins=range(18, 80, 10), labels=[f"{i}-{i+9}" for i in range(18, 70, 10)])

# Compter le nombre de personnes par tranche d'âge et genre
# Groupby avec observed=False pour conserver le comportement actuel
age_gender_count = df.groupby(["Age Group", "Gender"], observed=False).size().reset_index(name="Count")

# Graphique en barres
plt.figure(figsize=(10, 6))
sns.barplot(data=age_gender_count, x="Age Group", y="Count", hue="Gender")
palette = sns.color_palette("bright")[::-1]
plt.title("Nombre d'individus par tranche d'âge et par genre")
plt.xlabel("Tranche d'âge")
plt.ylabel("Nombre d'individus")
plt.legend(title="Genre")
plt.show()
output_41_0.png
# Purchase Amount Distribution
plt.figure(figsize=(12, 5))
sns.set(style="whitegrid")
sns.boxplot(x=df['Purchase Amount (USD)'], color='lightcoral')
plt.title('Boxplot of Purchase Amount', fontsize=16, fontweight='bold')

plt.xlabel('Purchase Amount', fontsize=14)
Text(0.5, 0, 'Purchase Amount')
output_42_1.png
# Calculer les statistiques de base pour la colonne 'Age'
purchase_stats = df['Purchase Amount (USD)'].describe()

# Afficher les valeurs du minimum, du maximum et de la médiane
print(f"Min: {purchase_stats['min']}")
print(f"Max: {purchase_stats['max']}")
print(f"Median: {purchase_stats['50%']}")
Min: 20.0
Max: 100.0
Median: 60.0
# Créer des catégories d'âge
bins = [18, 20, 30, 40, 50, 60, 70, 100]  # Définir les intervalles d'âge
labels = ['18-20', '20-30', '31-40', '41-50', '51-60', '61-70', '71+']  # Noms des catégories

# Ajouter une colonne avec les catégories d'âge
df['Age Group'] = pd.cut(df['Age'], bins=bins, labels=labels, right=False)

# Tracer un boxplot des dépenses en fonction des groupes d'âge
plt.figure(figsize=(12, 5))
sns.set(style="whitegrid")
sns.boxplot(x=df['Age Group'], y=df['Purchase Amount (USD)'], color='lightcoral')

# Ajouter les titres et labels
plt.title('Boxplot of Purchase Amount by Age Group', fontsize=16, fontweight='bold')
plt.xlabel('Age Group', fontsize=14)
plt.ylabel('Purchase Amount (USD)', fontsize=14)

# Affichage final
plt.tight_layout()
plt.show()
output_44_0.png

On remarque l’âge a peu d’influence sur le montant des achats.

size_counts = df['Size'].value_counts().reset_index()
size_counts.columns = ['Size', 'Count']
# Graphique en barres
plt.figure(figsize=(10, 6))
sns.barplot(data=size_counts, x="Size", y="Count", hue="Size")
palette = sns.color_palette("bright")[::-1]
plt.title("Taille les plus vendues")
plt.xlabel("Taille")
plt.ylabel("Nombre de produits vendus")
plt.show()
output_46_0.png

La taille M est de loin la plus vendue.

Couleurs les plus vendues

df["Color"].value_counts(normalize=True).reset_index()
Color proportion
0 Olive 0.045385
1 Yellow 0.044615
2 Silver 0.044359
3 Teal 0.044103
4 Green 0.043333
5 Black 0.042821
6 Cyan 0.042564
7 Violet 0.042564
8 Gray 0.040769
9 Maroon 0.040513
10 Orange 0.039487
11 Charcoal 0.039231
12 Pink 0.039231
13 Blue 0.038974
14 Magenta 0.038974
15 Purple 0.038718
16 Peach 0.038205
17 Red 0.037949
18 Beige 0.037692
19 Indigo 0.037692
20 Lavender 0.037692
21 Turquoise 0.037179
22 White 0.036410
23 Brown 0.036154
24 Gold 0.035385
fig, axes = plt.subplots(1, 2, figsize=(12, 4))

# Graphique de barres
sns.countplot(data=df, x="Color", ax=axes[0])
axes[0].set_xticks(range(len(df["Color"].unique())))  # Définir les ticks
axes[0].set_xticklabels(axes[0].get_xticklabels(), rotation=90)

# Diagramme circulaire
color_counts = df["Color"].value_counts()  # Assurez-vous que color_counts est défini
axes[1].pie(color_counts, labels=color_counts.index, startangle=90)

# Affichage des graphiques
plt.tight_layout()
plt.show()
output_50_0.png

On constate qu’il y a une répartition plutôt égale des couleurs des items vendus

Ventes par saison

season_counts = df["Season"].value_counts()
season_counts
Season
Spring    999
Fall      975
Winter    971
Summer    955
Name: count, dtype: int64
season = df["Season"].value_counts(normalize=1).reset_index()
# Count popular payment methods
season.columns = ['Season', 'Count']

# Créer un diagramme circulaire
fig = px.pie(
    season,
    names='Season',
    values='Count',
    title='Répartition des achats en en fontion des sainsons'
)
# Ajuster la taille et le titre
fig.update_layout(
    title={'text': 'Répartition des achats en en fontion des sainsons', 'x': 0.5, 'font': {'size': 18}},  # Taille du titre
    width=800,  # Largeur du graphique
    height=600  # Hauteur du graphique
)
# Afficher le graphique
fig.show()

On remarque la saison n’influe pas sur les ventes du site.

Notations

df["Review Rating"].describe()
count    3900.000000
mean        3.749949
std         0.716223
min         2.500000
25%         3.100000
50%         3.700000
75%         4.400000
max         5.000000
Name: Review Rating, dtype: float64
fig, axes = plt.subplots(1, 2, figsize=(12, 4))

sns.histplot(data=df, x="Review Rating", ax=axes[0], kde=True)
sns.boxplot(data=df, x="Review Rating", ax=axes[1])
<Axes: xlabel='Review Rating'>
output_58_1.png

La moyenne des avis est 3,75, avec un écart type de 0,72, indiquant une faible dispersion. Cela signifie que la plupart des avis sont concentrés entre 3,03 et 4,47. Les quartiles montrent que 50% des avis sont inférieurs à 3,7, mais que 75% sont inférieurs ou égaux à 4,4, ce qui reflète une appréciation généralement positive, avec peu de variations extrêmes.

Acheteurs ayant un compte

# Compter les utilisateurs selon leur statut d'abonnement
subscription = df["Subscription Status"].value_counts().reset_index()
subscription.columns = ['Subscription Status', 'Count']

# Créer un diagramme circulaire
fig = px.pie(
    subscription,
    names='Subscription Status',
    values='Count',
    title='Répartition des acheteurs ayant un compte',
    hole=0.4  # Optionnel : pour un graphique en anneau
)

# Ajuster la mise en page et ajouter des pourcentages
fig.update_traces(
    textinfo='percent+label',  # Affiche le pourcentage et l'étiquette
    hoverinfo='label+value+percent'  # Infos au survol : étiquette, valeur, pourcentage
)

# Ajuster le titre et la taille
fig.update_layout(
    title={'text': 'Répartition des acheteurs ayant un compte', 'x': 0.5, 'font': {'size': 18}},
    width=800,
    height=600
)

# Afficher le graphique
fig.show()

La grande majorité des acheteurs n’ont pas de compte sur le site

Acheteurs qui profitent des réductions proposées

df.columns
Index(['Customer ID', 'Age', 'Gender', 'Item Purchased', 'Category',
       'Purchase Amount (USD)', 'Location', 'Size', 'Color', 'Season',
       'Review Rating', 'Subscription Status', 'Payment Method',
       'Shipping Type', 'Discount Applied', 'Promo Code Used',
       'Previous Purchases', 'Preferred Payment Method',
       'Frequency of Purchases', 'Age Group'],
      dtype='object')
# Compter les utilisateurs selon leur statut d'abonnement
promo_code = df["Promo Code Used"].value_counts().reset_index()
promo_code.columns = ['Promo Code Used', 'Count']

# Créer un diagramme circulaire
fig = px.pie(
    promo_code,
    names='Promo Code Used',
    values='Count',
    title='Répartition des acheteurs utilisant un code promo',
    hole=0.4  # Optionnel : pour un graphique en anneau
)

# Ajuster la mise en page et ajouter des pourcentages
fig.update_traces(
    textinfo='percent+label',  # Affiche le pourcentage et l'étiquette
    hoverinfo='label+value+percent'  # Infos au survol : étiquette, valeur, pourcentage
)

# Ajuster le titre et la taille
fig.update_layout(
    title={'text': 'Répartition des acheteurs utilisant un code promo', 'x': 0.5, 'font': {'size': 18}},
    width=800,
    height=600
)

# Afficher le graphique
fig.show()

Une petite majorité des utilisateurs utilisent les Codes Promos proposés par le site

Réductions appliquées

# Compter les utilisateurs selon leur statut d'abonnement
discount = df["Discount Applied"].value_counts().reset_index()
discount.columns = ['Discount Applied', 'Count']

# Créer un diagramme circulaire
fig = px.pie(
    discount,
    names='Discount Applied',
    values='Count',
    title='Répartition des acheteurs ayant une remise',
)

# Ajuster la mise en page et ajouter des pourcentages
fig.update_traces(
    textinfo='percent+label',  # Affiche le pourcentage et l'étiquette
    hoverinfo='label+value+percent'  # Infos au survol : étiquette, valeur, pourcentage
)

# Ajuster le titre et la taille
fig.update_layout(
    title={'text': 'Répartition des acheteurs ayant une remise', 'x': 0.5, 'font': {'size': 18}},
    width=800,
    height=600
)

# Afficher le graphique
fig.show()

La majorité des acheteurs n’ont pas de remise

Visualisation du nombre d’achats déjà réalisés

df["Previous Purchases"].describe()
count    3900.000000
mean       25.351538
std        14.447125
min         1.000000
25%        13.000000
50%        25.000000
75%        38.000000
max        50.000000
Name: Previous Purchases, dtype: float64
fig, axes = plt.subplots(1, 2, figsize=(12, 4))

sns.histplot(data=df, x="Previous Purchases", ax=axes[0], kde=True)
sns.boxplot(data=df, x="Previous Purchases", ax=axes[1])
<Axes: xlabel='Previous Purchases'>
output_72_1.png

L’écart type des achats précédents est 14,45, ce qui indique une variabilité relativement importante autour de la moyenne 25,35. La plupart des données (environ 68%, si la distribution est normale) se situent dans l’intervalle approximatif [10,9 ; 39,8], tandis que les quartiles montrent que :

  • 25% des achats sont inférieurs à 13.

  • 50% sont inférieurs à 25.

  • 75% sont inférieurs à 38. Cela signifie que les achats précédents sont concentrés entre 13 et 38, mais avec une dispersion notable autour de la moyenne.

df["Frequency of Purchases"].describe()
count               3900
unique                 7
top       Every 3 Months
freq                 584
Name: Frequency of Purchases, dtype: object
fig, axes = plt.subplots(1, 2, figsize=(15, 5))

sns.histplot(data=df, x="Frequency of Purchases", ax=axes[0], kde=True)
sns.boxplot(data=df, x="Frequency of Purchases", ax=axes[1])
<Axes: xlabel='Frequency of Purchases'>
output_75_1.png

Méthodes de paiement

# Count popular payment methods
payment_counts = df['Payment Method'].value_counts().reset_index()
payment_counts.columns = ['Payment Method', 'Count']

# Créer un diagramme circulaire
fig = px.pie(
    payment_counts,
    names='Payment Method',
    values='Count',
    title='Répartition des méthodes de paiement populaires'
)
# Ajuster la taille et le titre
fig.update_layout(
    title={'text': "Répartition des méthodes de paiement", 'x': 0.5, 'font': {'size': 18}},  # Taille du titre
    width=800,  # Largeur du graphique
    height=600  # Hauteur du graphique
)
# Afficher le graphique
fig.show()

On peut remarquer qu’il n’y a pas de différence notable au niveau de la proportion des méthodes de paiement

# Créer des catégories d'âge
bins = [18, 20, 30, 40, 50, 60, 70, 100]  # Définir les intervalles d'âge
labels = ['18-20', '20-30', '31-40', '41-50', '51-60', '61-70', '71+']  # Noms des catégories

# Ajouter une colonne avec les catégories d'âge
df['Age Group'] = pd.cut(df['Age'], bins=bins, labels=labels, right=False)

# Tracer un boxplot des dépenses en fonction des groupes d'âge
plt.figure(figsize=(12, 5))
sns.set(style="whitegrid")
sns.boxplot(x=df['Age Group'], y=df['Payment Method'], color='lightcoral')

# Ajouter les titres et labels
plt.title('Boxplot of Payment Method by Age Group', fontsize=16, fontweight='bold')
plt.xlabel('Age Group', fontsize=14)
plt.ylabel('Purchase Amount (USD)', fontsize=14)

# Affichage final
plt.tight_layout()
plt.show()
output_79_0.png

On constate que chez les 20-30 ans et les 41-50 ans le mode de paiement le plus utilisé est Paypal, et que c’est le Cash pour le reste des transhces d’âge.

Mode de livraison

# Count popular payment methods
shipping = df['Shipping Type'].value_counts().reset_index()
shipping.columns = ['Shipping Type', 'Count']

# Créer un diagramme circulaire
fig = px.pie(
    shipping,
    names='Shipping Type',
    values='Count',
    title='Répartition des modes d`envoie populaires'
)
# Ajuster la taille et le titre
fig.update_layout(
    title={'text': "Répartition des modes d`envoie populaires", 'x': 0.5, 'font': {'size': 18}},  # Taille du titre
    width=800,  # Largeur du graphique
    height=600  # Hauteur du graphique
)
# Afficher le graphique
fig.show()
# Créer des catégories d'âge
bins = [18, 20, 30, 40, 50, 60, 70, 100]  # Définir les intervalles d'âge
labels = ['18-20', '20-30', '31-40', '41-50', '51-60', '61-70', '71+']  # Noms des catégories

# Ajouter une colonne avec les catégories d'âge
df['Age Group'] = pd.cut(df['Age'], bins=bins, labels=labels, right=False)

# Tracer un boxplot des dépenses en fonction des groupes d'âge
plt.figure(figsize=(12, 5))
sns.set(style="whitegrid")
sns.boxplot(x=df['Age Group'], y=df['Shipping Type'], color='lightcoral')

# Ajouter les titres et labels
plt.title("Boxplot des méthodes d`envoi par groupe d'age", fontsize=16, fontweight='bold')
plt.xlabel('Age Group', fontsize=14)
plt.ylabel('Purchase Amount (USD)', fontsize=14)

# Affichage final
plt.tight_layout()
plt.show()
output_83_0.png

On remarque que les 20-30 ans et les personnes de plus de 71 ans ont une préférence pour la livraison standard, tandis que les autres groupes d’âge préfère la livraion à J+1.